home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
225
/
amigatcp
/
src
/
ftp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
3KB
|
173 lines
/* Stuff common to both the FTP server and client */
#include <stdio.h>
#include "machdep.h"
#include "mbuf.h"
#include "netuser.h"
#include "timer.h"
#include "tcp.h"
#include "ftp.h"
#include "session.h"
#ifdef AMIGA
#define UNIX 1 /* UNIX semantics work for Amiga in this module */
#endif
/* FTP data channel receive upcall handler */
void
r_ftpd(tcb,cnt)
struct tcb *tcb;
int16 cnt;
{
register struct ftp *ftp;
struct mbuf *bp;
#ifdef UNIX
char c;
#endif
ftp = (struct ftp *)tcb->user;
if(ftp->state != RECEIVING_STATE){
close_tcp(tcb);
return;
}
/* This will likely also generate an ACK with window rotation */
recv_tcp(tcb,&bp,cnt);
#ifdef UNIX
while(pullup(&bp,&c,1) == 1){
if(ftp->type == IMAGE_TYPE || c != '\r')
putc(c,ftp->fp);
}
#else
while(bp != NULLBUF){
if(bp->cnt != 0)
fwrite(bp->data,1,(unsigned)bp->cnt,ftp->fp);
bp = free_mbuf(bp);
}
#endif
}
/* FTP data channel transmit upcall handler */
void
t_ftpd(tcb,cnt)
struct tcb *tcb;
int16 cnt;
{
struct ftp *ftp;
struct mbuf *bp;
char *cp;
int c;
#ifndef CPM
#ifndef AMIGA
char *cdsave,*pwd();
#endif
#endif
ftp = (struct ftp *)tcb->user;
if(ftp->state != SENDING_STATE){
close_tcp(tcb);
return;
}
if((bp = alloc_mbuf(cnt)) == NULLBUF){
/* Hard to know what to do here */
return;
}
cp = bp->data;
while(cnt > 1 && (c = getc(ftp->fp)) != EOF){
#ifdef CPM
if(ftp->type == ASCII_TYPE && c == CTLZ)
break; /* CTLZ is CP/M's text EOF marker */
#endif
#ifdef UNIX
if(ftp->type == ASCII_TYPE && c == '\n'){
*cp++ = '\r';
bp->cnt++;
cnt--;
}
#endif
*cp++ = c;
bp->cnt++;
cnt--;
}
if(bp->cnt != 0)
send_tcp(tcb,bp);
else
free_p(bp);
if(cnt > 1){ /* EOF seen */
#ifndef CPM
#ifndef AMIGA
cdsave = pwd(); /* Save current directory */
chdir(ftp->cd); /* Switch to user's directory*/
#endif
#endif
fclose(ftp->fp);
#ifndef CPM
#ifndef AMIGA
chdir(cdsave); /* And back */
free(cdsave);
#endif
#endif
ftp->fp = NULLFILE;
close_tcp(tcb);
}
}
/* Allocate an FTP control block */
struct ftp *
ftp_create(bufsize)
unsigned bufsize;
{
void ftp_delete();
char *calloc(),*malloc();
register struct ftp *ftp;
if((ftp = (struct ftp *)calloc(1,sizeof (struct ftp))) == NULLFTP)
return NULLFTP;
if(bufsize != 0 && (ftp->buf = malloc(bufsize)) == NULLCHAR){
ftp_delete(ftp);
return NULLFTP;
}
ftp->state = COMMAND_STATE;
ftp->type = ASCII_TYPE; /* Default transfer type */
return ftp;
}
/* Free resources, delete control block */
void
ftp_delete(ftp)
register struct ftp *ftp;
{
if(ftp->fp != NULLFILE)
fclose(ftp->fp);
if(ftp->data != NULLTCB)
del_tcp(ftp->data);
if(ftp->username != NULLCHAR)
free(ftp->username);
if(ftp->buf != NULLCHAR)
free(ftp->buf);
#ifndef AMIGA
if(ftp->cd != NULLCHAR)
free(ftp->cd);
#endif
if(ftp->session != NULLSESSION)
ftp->session->type = FREE;
free((char *)ftp);
}
#ifndef AMIGA
/* Call getcwd(), but stick a backslash on the front (!) */
#define CWDLEN 256 /* max path len */
char *
pwd()
{
char *buf,*malloc(),*getcwd();
if((buf = malloc(CWDLEN+1)) == NULLCHAR)
return NULLCHAR;
buf[0] = '\\';
if(getcwd(buf+1,CWDLEN) == NULLCHAR){
free(buf);
return NULLCHAR;
}
return buf;
}
#endif